package org.budo.ehcache.replicator.util;

import org.budo.ehcache.replicator.EhcacheReplicator;
import org.budo.ehcache.replicator.ReplicatorMessage;
import org.budo.support.spring.util.SpringUtil;

import lombok.extern.slf4j.Slf4j;
import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
import net.sf.ehcache.Ehcache;
import net.sf.ehcache.Element;

/**
 * @author lmw
 */
@Slf4j
public class EhcacheReplicatorUtil {
    public static final String NOTIFY_ELEMENT_REMOVED = "notifyElementRemoved";

    public static final String NOTIFY_REMOVE_ALL = "notifyRemoveAll";

    private static int _log_count = 0;

    /**
     * 控制日志量
     */
    public static void logError(String message) {
        if (_log_count < 100 //
                || (_log_count < 1000 && _log_count % 10 == 0) //
                || (_log_count < 10000 && _log_count % 100 == 0))
            log.error(message + ", _log_count=" + _log_count);
    }

    /**
     * 收到消息后的统一处理
     */
    public static void handleReplicatorMessage(ReplicatorMessage message, EhcacheReplicator ehcacheReplicator) {
        CacheManager cacheManager = SpringUtil.getBeanCached(CacheManager.class);

        String cacheName = message.getCacheName();
        Cache cache = cacheManager.getCache(cacheName);
        if (null == cache) {
            log.error("#46 onRedisMessage, cache[" + cacheName + "] not found, message=" + message);
            return;
        }

        if (NOTIFY_ELEMENT_REMOVED.equals(message.getEvent())) {
            cache.remove(message.getElementKey()); // 会进入 notifyElementRemoved 事件，由 publishRedisMessage 方法作筛选判断，不再次广播
            return;
        }

        if (NOTIFY_REMOVE_ALL.equals(message.getEvent())) {
            cache.removeAll(); // 会进入 notifyRemoveAll 事件，由 publishRedisMessage 方法作筛选判断，不再次广播
            return;
        }

        log.error("#55 onRedisMessage, event else, message=" + message + ", ehcacheReplicator=" + ehcacheReplicator);
    }

    /**
     * build replicatorMessage
     */
    public static ReplicatorMessage newReplicatorMessage(Ehcache cache, Element element, String event) {
        String cacheName = cache.getName();

        Object elementKey = null == element ? null : element.getObjectKey(); // notifyRemoveAll 事件没有特定 element
        String elementKeyStr = null;

        if (null == elementKey) {
            // elementKeyStr = null;
        } else if (elementKey instanceof String) { // 只支持string类型的key，@see #onRedisMessage(EhcacheRedisReplicatorEventMessage)
            elementKeyStr = (String) elementKey;
        } else {
            log.warn("#90 Cache.Element.Key should be String, cacheName=" + cacheName + ", elementKey=" + elementKey + ", event=" + event);
            elementKeyStr = elementKey.toString();
        }

        return new ReplicatorMessage() //
                .setEvent(event) //
                .setCacheName(cacheName) //
                .setElementKey(elementKeyStr);
    }
}